#include "my_allocator.h"
#include "stdlib.h"
#include "math.h"
#include "global_declarations.h"


/**
 * creates and initializes a new block.
 */
Block* create_new_block(int size) {
	Block* b = malloc(sizeof(Block));
	int block_size = ALLOCATOR_BLOCK_SIZE;
	if (size > ALLOCATOR_BLOCK_SIZE) {
		block_size = size;
	}
	b->size = block_size;
	b->memory = malloc(block_size);
	b->next = 0;
	b->occupied_size = 0;
	return b;
}

/**
 *creates and initializes a new MyAllocator
 */
MyAllocator* create_new_my_allocator(int blockSize) {
	MyAllocator* p = malloc(sizeof(MyAllocator));
	p->head = 0;
	return p;
}

/**
 *returns a pointer to an allocated memory (at least in the size n)
 */
void* my_allocate(MyAllocator* p, int n) {
	Block* cur_block, *new_block;
	cur_block = p->head;
	while (cur_block != 0){
		if (cur_block->size - cur_block->occupied_size >= n){
			cur_block->occupied_size += n;
			return cur_block->memory+cur_block->occupied_size-n;
		}
		cur_block = cur_block->next;
	}
	new_block = create_new_block(n);
	new_block->next = p->head;
	p->head = new_block;
	new_block->occupied_size = n;
	return new_block->memory;
}

/**
 *frees all allocated memory
 */
void clear_my_allocator(MyAllocator* p) {
	Block* cur_block, *next_block;
	cur_block = p->head;
	while(cur_block != 0){
		next_block = cur_block->next;
		free(cur_block->memory);
		free(cur_block);
		cur_block = next_block;
	}
	p->head = 0;
}
